﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Mvc;
using WalkingTec.Mvvm.Core.Extensions;
using System.Linq;
using System.Collections.Generic;
using nERP.Model.Rpt;
using nERP.ViewModel.Rpt.DashboardVMs;
using nERP.Model;
using nERP.Model.Bas;
using nERP.Model.Po;
using nERP.Model.Fin;
using nERP.Model.So;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using nERP.Model.Wms;
using Microsoft.EntityFrameworkCore;
using System.Data;
using FluentStorage.Utils.Extensions;
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Identity;
using NPOI.SS.Formula.Functions;

namespace nERP.Rpt.Controllers
{
    [AuthorizeJwtWithCookie]
    [ActionDescription("_Model.Dashboard")]
    [ApiController]
    [Route("/api/Rpt/Dashboard")]
    [AllRights]
    public partial class DashboardController : BaseApiController
    {
        [ActionDescription("Sys.Get")]
        [HttpGet("{id}")]
        public IActionResult Get(string id)
        {
            var vm = Wtm.CreateVM<DashboardVM>(id);
            return Ok(vm);
        }

        [ActionDescription("Sys.Create")]
        [HttpPost("[action]")]
        public async Task<IActionResult> Create(DashboardVM vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                await vm.DoAddAsync();

                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState.GetErrorJson());
                }
                else
                {
                    return Ok(vm.Entity);
                }
            }

        }

        [ActionDescription("Sys.Edit")]
        [HttpPut("[action]")]
        public async Task<IActionResult> Edit(DashboardVM vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                await vm.DoEditAsync(false);
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState.GetErrorJson());
                }
                else
                {
                    return Ok(vm.Entity);
                }
            }
        }


        [HttpPost("BatchEdit")]
        [ActionDescription("Sys.BatchEdit")]
        public ActionResult BatchEdit(DashboardBatchVM vm)
        {
            if (!ModelState.IsValid || !vm.DoBatchEdit())
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                return Ok(vm.Ids.Count());
            }
        }

        [HttpPost("BatchDelete")]
        [ActionDescription("Sys.Delete")]
        public IActionResult BatchDelete(string[] ids)
        {
            var vm = Wtm.CreateVM<DashboardBatchVM>();
            if (ids != null && ids.Count() > 0)
            {
                vm.Ids = ids;
            }
            else
            {
                return Ok();
            }
            if (!ModelState.IsValid || !vm.DoBatchDelete())
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                return Ok(ids.Count());
            }
        }

        [ActionDescription("Sys.DownloadTemplate")]
        [HttpGet("GetExcelTemplate")]
        public IActionResult GetExcelTemplate()
        {
            var vm = Wtm.CreateVM<DashboardImportVM>();
            var qs = new Dictionary<string, string>();
            foreach (var item in Request.Query.Keys)
            {
                qs.Add(item, Request.Query[item]);
            }
            vm.SetParms(qs);
            var data = vm.GenerateTemplate(out string fileName);
            return File(data, "application/vnd.ms-excel", fileName);
        }

        [ActionDescription("Sys.Import")]
        [HttpPost("Import")]
        public ActionResult Import(DashboardImportVM vm)
        {

            if (vm.ErrorListVM.EntityList.Count > 0 || !vm.BatchSaveData())
            {
                return BadRequest(vm.GetErrorJson());
            }
            else
            {
                return Ok(vm.EntityList.Count);
            }
        }

        [HttpGet("GetDashboard")]
        [AllRights]
        public ActionResult GetDashboard()
        {
            var query = DC.Set<Dashboard>()

                .Select(x => new Dashboard
                {
                    ID = x.ID,

                    Monthly = x.Monthly,
                    PoAmount = DC.Set<Buy>().Sum(z => z.TotalPrice),
                    PoAmounted = DC.Set<Buy>().Where(z => z.Status == StatusTypeEnum.Reviewed).Sum(z => z.TotalPrice),
                    SoAmount = DC.Set<Sale>().Sum(z => z.TotalPrice),
                    SoAmounted = DC.Set<Sale>().Where(z => z.Status == StatusTypeEnum.Reviewed).Sum(z => z.TotalPrice),
                    PayAmount = DC.Set<Payment>().Sum(z => z.TotalPrice),
                    PayAmounted = DC.Set<Payment>().Where(z => z.Status == StatusTypeEnum.Reviewed).Sum(z => z.TotalPrice),
                    ReceivableAmount = DC.Set<Receivable>().Sum(z => z.TotalPrice),
                    ReceivableAmounted = DC.Set<Receivable>().Where(z => z.Status == StatusTypeEnum.Reviewed).Sum(z => z.TotalPrice),
                }).SingleOrDefault();

            return Ok(query);


        }

        [HttpGet("GetDashboardPie")]
        [AllRights]
        public ActionResult GetDashboardPie()
        {
            //string sql = @"select GoodName,sum(BuyInNumber) BuyInNumber from
            //                        (select GoodsId, BuyInNumber,
            //                        case  when DATEDIFF(day,CreateTime,getdate()) <=30 then '10-30'
            //                        when DATEDIFF(day,CreateTime,getdate()) >30 and DATEDIFF(day,CreateTime,getdate())<=60 then '231-60'
            //                        when DATEDIFF(day,CreateTime,getdate()) >60 and DATEDIFF(day,CreateTime,getdate())<=90 then '361-90'
            //                        when DATEDIFF(day,CreateTime,getdate()) >90 and DATEDIFF(day,CreateTime,getdate())<=180 then '491-180'
            //                        when DATEDIFF(day,CreateTime,getdate()) >180 and DATEDIFF(day,CreateTime,getdate())<=360 then '5181-360'
            //                        when DATEDIFF(day,CreateTime,getdate()) >360  then '6360++' ";
            //sql += string.Format(@" end GoodName from BuyInWarehouseDetail {0}) a  group by GoodName"
            //    , Wtm.LoginUserInfo.TenantCode == null ? "" : string.Format(@" where TenantCode='{0}'", Wtm.LoginUserInfo.TenantCode));

            ////var t = Wtm.LoginUserInfo.TenantCode;

            ////var query = DC.Set<BuyInWarehouseDetail>().FromSql($"{sql}").FirstOrDefault();
            //var dt = DC.RunSQL(sql);
            //if (dt == null || dt.Rows.Count < 1) return BadRequest(ModelState.GetErrorJson());

            var buyStoreage = DC.Set<BuyInWarehouseDetail>()
                  .Select(x => new BuyInWarehouseDetail
                  {
                      //GoodsId = x.GoodsId,
                      BuyInNumber = x.BuyInNumber,
                      GoodsId = DateTime.Now.Subtract(x.CreateTime ?? DateTime.Now).Days <= 30 ? "10-30" :
                      (DateTime.Now.Subtract(x.CreateTime ?? DateTime.Now).Days > 30 && DateTime.Now.Subtract(x.CreateTime ?? DateTime.Now).Days <= 60 ? "231-60" :
                      (DateTime.Now.Subtract(x.CreateTime ?? DateTime.Now).Days > 60 && DateTime.Now.Subtract(x.CreateTime ?? DateTime.Now).Days <= 90 ? "361-90" :
                      (DateTime.Now.Subtract(x.CreateTime ?? DateTime.Now).Days > 90 && DateTime.Now.Subtract(x.CreateTime ?? DateTime.Now).Days <= 180 ? "491-180" :
                      (DateTime.Now.Subtract(x.CreateTime ?? DateTime.Now).Days > 180 && DateTime.Now.Subtract(x.CreateTime ?? DateTime.Now).Days <= 360 ? "5181-360" : "6360++")))),
                  }).ToList()
                  .GroupBy(x => x.GoodsId)
                  .Select(x => new BuyInWarehouseDetail
                  {
                      GoodsId = x.Key,
                      BuyInNumber = x.Sum(z => z.BuyInNumber)
                  });


            return Ok(buyStoreage);


        }
        [HttpGet("GetDashboardInTop")]
        [AllRights]
        public ActionResult GetDashboardInTop()
        {
            var storeageSum = DC.Set<BuyInWarehouseDetail>().Sum(x => x.BuyInNumber);
            var buyStoreage = DC.Set<BuyInWarehouseDetail>()
                .GroupBy(x => x.GoodsId)
                .Select(x => new Buy
                {
                    BuyCode = x.Key,
                    TotalPrice = x.Sum(z => z.BuyInNumber),
                    TotalPrice1 = x.Sum(z => z.BuyInNumber) / storeageSum * 100
                })
                 .OrderByDescending(x => x.TotalPrice)
                .Take(10);
            return Ok(buyStoreage);
        }
        [HttpGet("GetDashboardOutTop")]
        [AllRights]
        public ActionResult GetDashboardOutTop()
        {
            var storeageSum = DC.Set<SaleOutWarehouseDetail>().Sum(x => x.SaleOutNumber);
            var saleStoreage = DC.Set<SaleOutWarehouseDetail>()
                .GroupBy(x => x.GoodsId)
                .Select(x => new Sale
                {
                    SaleCode = x.Key,
                    TotalPrice = x.Sum(z => z.SaleOutNumber),
                    TotalPrice1 = x.Sum(z => z.SaleOutNumber) / storeageSum * 100
                })
                 .OrderByDescending(x => x.TotalPrice)
                .Take(10);
            return Ok(saleStoreage);
        }
    }
}